package basemod

import (
	"sync"
	"reflect"
	"strconv"
	"strings"
	"runtime/debug"

	"gitee.com/wint/tge/log"
)

// 网络数据接收者
type NetDataProcessing struct {
	sync.RWMutex	// 线程锁

	reqs 	map[uint16]func(IMsgPack)uint16
	reqAsyns 	map[uint16]func(IMsgPack)uint16

	Impl 	interface{}
}

// 设置实际对象
func (r *NetDataProcessing) SetImpl(impl interface{}) {
	r.Impl = impl

	// 根据函数名 自动绑定网络响应函数
	value := reflect.ValueOf(impl)
	typ := value.Type()
	for i := 0; i < typ.NumMethod(); i++ {
		method := typ.Method(i)
		if strings.Index(method.Name, "OnReq") == 0 {
			s2 := method.Name[5:]
			if id, err := strconv.ParseInt(s2, 10, 32); err == nil {
				mt := value.MethodByName(method.Name)
				r.REQ(uint16(id), func(pack IMsgPack) uint16 {
					resp := mt.Call([]reflect.Value{reflect.ValueOf(pack)})
					var intVal uint64
					intVal = resp[0].Uint()
					return uint16(intVal)
				})	
			}
		}
	}
}

func (r *NetDataProcessing) DoMsg(pack IMsgPack) uint16 {
	defer func() {
		if err := recover(); err != nil {
			log.Print("NetDataProcessing ERROR: ", err, string(debug.Stack()))
		}
	} ()

	if nil != r.reqAsyns {
		if h, ok := r.reqAsyns[pack.GetMsg().GetProtoId()]; ok {
			return h(pack)
		}
	}
	if nil != r.reqs {
		if h, ok := r.reqs[pack.GetMsg().GetProtoId()]; ok {
			r.Lock()
			defer r.Unlock()
			return h(pack)
		}
	}

	if nil != r.Impl {
		if req, ok := r.Impl.(IDefaultModREQ); ok {
			r.Lock()
			defer r.Unlock()
			return req.OnDefaultREQ(pack)
		}
	}

	return 0
}

// 注册同步请求响应
func (r *NetDataProcessing) REQ(protoId uint16, h func(IMsgPack)uint16) {
	if nil == r.reqs {
		r.reqs = make(map[uint16]func(IMsgPack)uint16)
	}
	r.reqs[protoId] = h
}

// 注册异步请求响应
func (r *NetDataProcessing) REQAsyn(protoId uint16, h func(IMsgPack)uint16) {
	if nil == r.reqAsyns {
		r.reqAsyns = make(map[uint16]func(IMsgPack)uint16)
	}
	r.reqAsyns[protoId] = h
}
